<template>
	<div :id="uploadId" class="fm-uplaod-container">
		<div v-for="item in fileList" :id="item.key" :key="item.key" :style="{ width: width + 'px', height: height + 'px' }" :class="{ uploading: item.status == 'uploading', 'is-success': item.status == 'success' }" class="upload-file">
			<img :src="item.url" />

			<el-progress v-if="item.status == 'uploading'" :width="miniWidth * 0.9" :percentage="item.percent" class="upload-progress" type="circle"></el-progress>

			<label v-if="item.status == 'success'" class="item-status">
				<i class="el-icon-upload-success el-icon-check"></i>
			</label>

			<div class="uplaod-action">
				<i :style="{ 'font-size': miniWidth / 4 + 'px' }" class="el-icon-view" @click="handlePreviewFile(item.key)"></i>
				<i :style="{ 'font-size': miniWidth / 4 + 'px' }" class="el-icon-delete" @click="handleRemove(item.key)"></i>
			</div>
		</div>

		<div v-if="token" :style="{ width: width + 'px', height: height + 'px' }" class="el-upload el-upload--picture-card">
			<i :style="{ fontSize: miniWidth / 4 + 'px', marginTop: -miniWidth / 8 + 'px', marginLeft: -miniWidth / 8 + 'px' }" class="el-icon-plus"></i>
			<input ref="uploadInput" :style="{ width: width + 'px', height: height + 'px' }" accept="image/* " multiple type="file" name="file" class="el-upload__input upload-input" @change="handleChange" />
		</div>
	</div>
</template>

<script>
// import Viewer from "viewerjs";
// require("viewerjs/dist/viewer.css");

export default {
	props: {
		value: {
			type: Array,
			default: () => [],
		},
		width: {
			type: Number,
			default: 100,
		},
		height: {
			type: Number,
			default: 100,
		},
		token: {
			type: String,
			default: '',
		},
		domain: {
			type: String,
			default: '',
		},
		multiple: {
			type: Boolean,
			default: true,
		},
		length: {
			type: Number,
			default: 9,
		},
	},
	data() {
		return {
			fileList: [],
			viewer: null,
			uploadId: 'upload_' + new Date().getTime(),
		};
	},
	computed: {
		miniWidth() {
			if (this.width > this.height) {
				return this.height;
			} else {
				return this.width;
			}
		},
	},
	methods: {
		handleChange() {
			const files = this.$refs.uploadInput.files;

			for (let i = 0; i < files.length; i++) {
				const file = files[i];
				const reader = new FileReader();
				const key = new Date().getTime() + '_' + Math.ceil(Math.random() * 99999);

				reader.readAsDataURL(file);
				reader.onload = () => {
					this.fileList.push({
						key,
						url: reader.result,
						percent: 0,
						status: 'uploading',
					});

					this.$nextTick(() => {
						this.uplaodAction(reader.result, file, key);
					});
				};
			}

			this.$refs.uploadInput.value = [];
		},

		uplaodAction(res, file, key) {
			const xhr = new XMLHttpRequest();
			const url = 'http://upload-z2.qiniu.com/putb64/' + file.size;
			xhr.open('POST', url, true);
			xhr.setRequestHeader('Content-Type', 'application/octet-stream');
			xhr.setRequestHeader('Authorization', 'UpToken ' + this.token);
			xhr.send(res.split(',')[1]);
			xhr.onreadystatechange = () => {
				if (xhr.readyState === 4) {
					const resData = JSON.parse(xhr.response);
					if (resData) {
						this.$set(
							this.fileList,
							this.fileList.findIndex((item) => item.key === key),
							{
								...this.fileList[this.fileList.findIndex((item) => item.key === key)],
								url: this.domain + resData.key,
								percent: 100,
							}
						);
						setTimeout(() => {
							this.$set(
								this.fileList,
								this.fileList.findIndex((item) => item.key === key),
								{
									...this.fileList[this.fileList.findIndex((item) => item.key === key)],
									status: 'success',
								}
							);

							this.$emit('input', this.fileList);
						}, 200);
					} else {
						this.$set(
							this.fileList,
							this.fileList.findIndex((item) => item.key === key),
							{
								...this.fileList[this.fileList.findIndex((item) => item.key === key)],
								status: 'error',
							}
						);
						this.fileList.splice(
							this.fileList.findIndex((item) => item.key === key),
							1
						);
					}
				}
			};
			xhr.onprogress = (res) => {
				// ('progress', res)
				if (res.total && res.loaded) {
					this.$set(this.fileList[this.fileList.findIndex((item) => item.key === key)], 'percent', (res.loaded / res.total) * 100);
				}
			};
		},

		handleRemove(key) {
			this.fileList.splice(
				this.fileList.findIndex((item) => item.key === key),
				1
			);
		},

		handlePreviewFile(key) {
			this.viewer && this.viewer.destroy();
			this.uploadId = 'upload_' + new Date().getTime();

			this.$nextTick(() => {
				this.viewer = new Viewer(document.getElementById(this.uploadId));
				this.viewer.view(this.fileList.findIndex((item) => item.key === key));
			});
		},
	},
};
</script>

<style lang="scss">
.fm-uplaod-container {
	.upload-file {
		margin: 0 10px 10px 0;
		display: inline-flex;
		justify-content: center;
		align-items: center;
		//  background: #fff;
		overflow: hidden;
		background-color: #fff;
		border: 1px solid #c0ccda;
		border-radius: 6px;
		box-sizing: border-box;
		position: relative;
		vertical-align: top;

		&:hover {
			.uplaod-action {
				display: flex;
			}
		}

		.uplaod-action {
			position: absolute;
			top: 0;
			bottom: 0;
			left: 0;
			right: 0;
			background: rgba(0, 0, 0, 0.6);
			display: none;
			justify-content: center;
			align-items: center;

			i {
				color: #fff;
				cursor: pointer;
				margin: 0 5px;
			}
		}

		&.is-success {
			.item-status {
				position: absolute;
				right: -15px;
				top: -6px;
				width: 40px;
				height: 24px;
				background: #13ce66;
				text-align: center;
				transform: rotate(45deg);
				box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);

				& > i {
					font-size: 12px;
					margin-top: 11px;
					color: #fff;
					transform: rotate(-45deg);
				}
			}
		}

		&.uploading {
			&:before {
				display: block;
				content: '';
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				bottom: 0;
				background: rgba(0, 0, 0, 0.3);
			}
		}

		.upload-progress {
			position: absolute;

			.el-progress__text {
				color: #fff;
				font-size: 16px !important;
			}
		}

		img {
			max-width: 100%;
			max-height: 100%;
			vertical-align: middle;
		}
	}

	.el-upload--picture-card {
		position: relative;
		overflow: hidden;

		.el-icon-plus {
			position: absolute;
			top: 50%;
			left: 50%;
		}
	}

	.upload-input {
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		display: block;
		opacity: 0;
		cursor: pointer;
	}
}
</style>
